package com.candy.biz.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.candy.biz.domain.dto.SysUserDTO;
import com.candy.common.annotations.Dict;
import com.candy.common.constant.CommonConstant;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import net.bytebuddy.ByteBuddy;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.implementation.FixedValue;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 公共管理类
 *
 * @author rong xi
 * @version 1.0
 * @date 2023/10/18 11:32
 */
@Slf4j
public class CommonManager {

    /**
     * 扩展vo其他信息
     *
     * @param list vo集合
     * @return vo集合
     * @param <T> vo类型
     */
    public static <T> List<T> convert(List<?> list, Class<T> clazz) {
        return list.stream()
                .map(e->convert(e,clazz))
                .collect(Collectors.toList());
    }

    /**
     * 扩展vo其他信息
     *
     * @param obj 原始对象
     * @param clazz 要转换类型class
     * @return vo
     * @param <T> vo类型
     */
    public static <T> T convert(@NonNull Object obj, Class<T> clazz) {
        T t = BeanUtil.copyProperties(obj, clazz);
        try{
            DynamicType.Builder<? extends T> byteBuddy = new ByteBuddy().subclass(clazz);
            for (Field field : ReflectUtil.getFields(clazz)) {
                //开启请求权限
                field.setAccessible(true);
                //赋值现有字段值
                if (field.get(t) != null) {
                    byteBuddy = byteBuddy
                            .method(ElementMatchers.named("get" + StrUtil.upperFirst(field.getName())))
                            .intercept(FixedValue.value(field.get(t)));
                }

                if(CommonConstant.DEFAULT_CREATE_USER_ID.equals(field.getName())){
                    //创建人名称
                    Long userId = field.get(t) == null?null:Long.valueOf(field.get(t).toString());
                    String userName = userId == null?"":SysUserManager.getUserInfoOpt(userId).map(SysUserDTO::getUserName).orElse("");
                    String userNameFieldName = field.getName() + "Name";
                    byteBuddy = byteBuddy.defineField(userNameFieldName, String.class, Modifier.PRIVATE)
                            .defineMethod("get" + StrUtil.upperFirst(userNameFieldName), String.class, Modifier.PUBLIC)
                            .intercept(FixedValue.value(userName));

                } else if(CommonConstant.DEFAULT_UPDATE_USER_ID.equals(field.getName())){
                    //修改人名称
                    Long userId = field.get(t) == null?null:Long.valueOf(field.get(t).toString());
                    String userName = userId == null?"":SysUserManager.getUserInfoOpt(userId).map(SysUserDTO::getUserName).orElse("");
                    String userNameFieldName = field.getName() + "Name";
                    byteBuddy = byteBuddy.defineField(userNameFieldName, String.class, Modifier.PRIVATE)
                            .defineMethod("get" + StrUtil.upperFirst(userNameFieldName), String.class, Modifier.PUBLIC)
                            .intercept(FixedValue.value(userName));
                } else if (field.getAnnotation(Dict.class) != null && field.get(t) != null) {
                    //赋值字典值名称
                    //字典枚举class
                    Class<?> enumClass = field.getAnnotation(Dict.class).dictEnum();
                    //获取key方法
                    String valueMethod = field.getAnnotation(Dict.class).getValueMethod();
                    //字典code
                    String dictCode = field.getAnnotation(Dict.class).value();
                    //字典项名称
                    Object dictItemName = "";
                    if (enumClass != null && !enumClass.equals(Object.class)) {
                        dictItemName = enumClass.getMethod(valueMethod, new Class<?>[]{field.getType()}).invoke(null, field.get(t));
                    } else if (StrUtil.isNotBlank(dictCode)) {
                        dictItemName = SysDictManager.getDictItemName(dictCode, field.get(t).toString());
                    }

                    String dictNameFieldName = field.getName() + "Name";
                    byteBuddy = byteBuddy.defineField(dictNameFieldName, String.class, Modifier.PRIVATE)
                            .defineMethod("get" + StrUtil.upperFirst(dictNameFieldName), String.class, Modifier.PUBLIC)
                            .intercept(FixedValue.value(dictItemName));
                }
            }

            return byteBuddy
                    .make()
                    .load(CommonManager.class.getClassLoader())
                    .getLoaded()
                    .getDeclaredConstructor()
                    .newInstance();
        } catch (Exception ex) {
            log.error("vo扩展信息异常:", ex);
            return t;
        }


    }
}
